package org.hope.cordinator;

import java.util.ArrayList;
import java.util.List;

import org.hope.db.RelationalSearchCordinator;
import org.hope.nlp.ParserFactory;
import org.hope.nlp.SearchTerm;
import org.hope.nlp.TextParser;
import org.hope.ontology.OntologySearchCordinator;
import org.hope.result.City;
import org.hope.result.RefineCriteria;
import org.hope.result.Result;
import org.hope.util.CodeValuePair;
import org.hope.util.Constants;
import org.hope.util.HopeLogger;
import org.hope.util.ReturnData;

/**
 * search coordinator
 * 
 * @author Thilanka
 */
public class SearchCordinator
{
	TextParser textParser;
	OntologySearchCordinator ontologySearchCordinator;
	RelationalSearchCordinator relationalSearchCordinator;

	public ReturnData<String> initMembers()
	{
		ReturnData<String> returnData = new ReturnData<String>( Constants.SUCCESS, "" );

		try
		{
			textParser = ParserFactory.getTextParser( ParserFactory.STANFORD_PARSER );
			textParser.init();

			ontologySearchCordinator = new OntologySearchCordinator();
			ontologySearchCordinator.init();

			relationalSearchCordinator = new RelationalSearchCordinator();

		}
		catch ( Exception e )
		{
			e.printStackTrace();
			returnData.setNo( Constants.ERROR );
			returnData.setMsg( e.getMessage() );
		}

		return returnData;
	}

	public List<Result> search( String text )
	{
		List<Result> results = new ArrayList<Result>();

		HopeLogger.log( "----------- Get search terms -----------" );
		// first get the search terms
		List<SearchTerm> searchTerms = textParser.getTerms( text );
		for ( SearchTerm searchTerm : searchTerms )
		{
			HopeLogger.log( searchTerm.toString() );
		}
		HopeLogger.log( "----------- Get search terms completed -----------" );

		results = ontologySearchCordinator.searchOntology( searchTerms );

		// we have to create rules here
		List<City> locations = new ArrayList<City>();
		int filterCount = 0;
		for ( Result result : results )
		{
			if ( result.getResultType() == Result.RESULT_TYPE_CITY )
			{
				locations.add( ( City ) result );
			}
			else if ( result.getResultType() == Result.RESULT_TYPE_CRITERA )
			{
				filterCount++;
			}
		}
		if ( locations.size() > 1 )
		{
			RefineCriteria refineCriteria = getRefineCriteria( locations, filterCount );
			results.add( refineCriteria );
		}

		// fill the hotel details from the relational database
		try
		{
			relationalSearchCordinator.fillDetails( results );
		}
		catch ( Exception e1 )
		{
			e1.printStackTrace();
		}
		
		// finally do the relational database search
		try
		{
			results.addAll( relationalSearchCordinator.search( locations ) );
		}
		catch ( Exception e )
		{
			e.printStackTrace();
		}

		return results;
	}

	private RefineCriteria getRefineCriteria( List<City> locations, int filterCount )
	{
		RefineCriteria refineCriteria = new RefineCriteria();

		refineCriteria.setQuestion( "What is the city that you want to go ?" );
		refineCriteria.setCode( Constants.FILTER + Constants.FILTER_SEPERATOR + filterCount );
		for ( City location : locations )
		{
			CodeValuePair<String, String> codeValuePair = new CodeValuePair<String, String>( location.getCode(), location.getReference() );
			refineCriteria.getOptions().add( codeValuePair );
		}

		return refineCriteria;
	}
}
